package com.bjpowernode.controller;

import com.bjpowernode.beans.Stu;
import com.bjpowernode.exception.MyNumberException;
import com.bjpowernode.exception.MyTextException;
import com.bjpowernode.services.StuServices;
import com.bjpowernode.services.StuServicesImp;
import com.bjpowernode.view.AddOrEditDialog;
import com.bjpowernode.view.MyAlert;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;

import java.net.URL;
import java.time.LocalDate;
import java.util.*;

public class StuViewController implements Initializable {
    StuServices stuServices = new StuServicesImp();


    @FXML
    private Button btnAdd;
    @FXML
    private Button btnDel;

    @FXML
    private Button btnEdit;

    @FXML
    private Button btnSelectByAll;

    @FXML
    private Button btnRandom;
    @FXML
    private TextField tInputName;
    @FXML
    private TableView<Stu> table;
    @FXML
    private TableColumn<Stu, Integer> colId;

    @FXML
    private TableColumn<Stu, String> colName;

    @FXML
    private TableColumn<Stu, String> colSex;

    @FXML
    private TableColumn<Stu, LocalDate> colAge;

    @FXML
    private TableColumn<Stu, Float> colScore;


    @FXML
    void sortAge(ActionEvent event) {
        ArrayList<Stu> stus = stuServices.sortByAge();
        ObservableList<Stu> stuObservableList = FXCollections.observableArrayList(stus);
        table.setItems(stuObservableList);
    }

    @FXML
    void sortId(ActionEvent event) {
        ArrayList<Stu> stus = stuServices.sortById();
        ObservableList<Stu> stuObservableList = FXCollections.observableArrayList(stus);
        table.setItems(stuObservableList);
    }

    @FXML
    void sortScore(ActionEvent event) {
        ArrayList<Stu> stus = stuServices.sortByScore();
        ObservableList<Stu> stuObservableList = FXCollections.observableArrayList(stus);
        table.setItems(stuObservableList);
    }

    @FXML
    void sortSex(ActionEvent event) {
        ArrayList<Stu> stus = stuServices.sortBySex();
        ObservableList<Stu> stuObservableList = FXCollections.observableArrayList(stus);
        table.setItems(stuObservableList);
    }


    @FXML
    void add(ActionEvent event) {
        //TODO 添加学生逻辑
        try {
            HashMap<String, Object> hashMap = AddOrEditDialog.dialogCreate("../view/stuAddOrEdit.fxml", "学生界面添加");
            DialogPane dialogPane = (DialogPane) hashMap.get(AddOrEditDialog.ResultType.DIALOGPANE);
            TextField tId = (TextField) dialogPane.lookup("#tId");
            TextField tName = (TextField) dialogPane.lookup("#tName");
            RadioButton rMan = (RadioButton) dialogPane.lookup("#rMan");
            RadioButton rWoMan = (RadioButton) dialogPane.lookup("#rWoMan");
            DatePicker dpAge = (DatePicker) dialogPane.lookup("#dpAge");
            TextField tScore = (TextField) dialogPane.lookup("#tScore");


            int lookID = stuServices.lookID();
            tId.setText(String.valueOf(lookID));
            tId.setEditable(false);
            Dialog<ButtonType> dialog = (Dialog<ButtonType>) hashMap.get(AddOrEditDialog.ResultType.DIALOG);
            Optional<ButtonType> buttonType = dialog.showAndWait();
            if (buttonType.get() == ButtonType.OK) {


                //控制器负责判定输入数据是否不为空
                //控制器负责判定输入数据是否为正确数据类型
                //业务负责判定输入数据是否为正确数据内容（范围、内容、排列组合等等）


                //学生姓名判定*******************************************
                //用户输入完毕
                String name = tName.getText();
                //去掉空格
                name = name.trim();
                if (name.length() > 5 || name.length() == 0) {
                    throw new MyTextException("学生姓名错误");
                }

                //学生年龄判定*******************************************
                LocalDate value = dpAge.getValue();
                if (value == null) {
                    throw new MyTextException("请输入学生年龄");
                }


                //学生分数判定*******************************************
                //分数判断
                String score = tScore.getText();
                //转换
                Float fScore = Float.valueOf(score);

                //添加
                Stu stu = new Stu();
                //真的添加了
                //学生并不在控制器中显示产生设置id的行为
                stu.setName(name);
                stu.setAge(dpAge.getValue());
                if (rMan.isSelected()) {
                    stu.setSex("男");
                } else {
                    stu.setSex("女");
                }
                stu.setScore(fScore);
                //调业务
                stuServices.add(stu);
                //学生表格刷新
                selectByAll(event);
            }

        } catch (MyTextException e) {
            MyAlert.alertOpen(e.getMessage(), "报错", ButtonType.CLOSE);
        } catch (NumberFormatException e) {
            MyAlert.alertOpen("分数输入错误", "报错", ButtonType.CLOSE);
        } catch (MyNumberException e) {
            MyAlert.alertOpen(e.getMessage(), "报错", ButtonType.CLOSE);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    @FXML
    void del(ActionEvent event) {
        //TODO 删除学生逻辑

        //返回表格选择模式
        TableView.TableViewSelectionModel<Stu> selectionModel = table.getSelectionModel();
        //如果没有选择任何学生
        //表格选中的index（行或者下标的概念），0开始，-1代表没有选择任何
        if (selectionModel.getSelectedIndex() == -1) {
            MyAlert.alertOpen("你没有选择任何学生", "提示", ButtonType.CLOSE);
            return;
        }

        //返回选择的学生
        Stu selectedItem = selectionModel.getSelectedItem();
        //删除确认
        Optional<ButtonType> buttonType = MyAlert.alertOpen("是否要删除【" + selectedItem.toString() + "】的信息", "提示", ButtonType.YES, ButtonType.NO);

        if (buttonType.get() == ButtonType.NO) {
            //如果选择不删除，则停止程序
            return;
        }

        //删除学生
        try {
            stuServices.del(selectedItem);
            //删除成功了在这里全查
            selectByAll(event);
        } catch (MyNumberException e) {
            e.printStackTrace();
            MyAlert.alertOpen(e.getMessage(), "提示", ButtonType.CLOSE);
        }


    }

    @FXML
    void edit(ActionEvent event) {
        //TODO 编辑学生逻辑
        //选择一个学生进行修改
        TableView.TableViewSelectionModel<Stu> selectionModel = table.getSelectionModel();
        int selectedIndex = selectionModel.getSelectedIndex();
        if (selectedIndex == -1) {
            MyAlert.alertOpen("请选择一个学生", "提示", ButtonType.CLOSE);
            return;
        }


        //获取选中的学生
        //这个表格选中的学生对象，是不是DB.stus集合里面的对象
        Stu selectedStuItem = selectionModel.getSelectedItem();


        HashMap<String, Object> hashMap = null;
        try {
            //开始给组件赋值选中的学生属性
            hashMap = AddOrEditDialog.dialogCreate("../view/stuAddOrEdit.fxml", "学生编辑");
            DialogPane dialogPane = (DialogPane) hashMap.get(AddOrEditDialog.ResultType.DIALOGPANE);
            //获取各个组件的对象
            TextField tId = (TextField) dialogPane.lookup("#tId");
            TextField tName = (TextField) dialogPane.lookup("#tName");
            RadioButton rMan = (RadioButton) dialogPane.lookup("#rMan");
            RadioButton rWoMan = (RadioButton) dialogPane.lookup("#rWoMan");
            DatePicker dpAge = (DatePicker) dialogPane.lookup("#dpAge");
            TextField tScore = (TextField) dialogPane.lookup("#tScore");
            //设置各个组件的初始值
            tId.setEditable(false);
            tId.setText(String.valueOf(selectedStuItem.getId()));
            tName.setText(selectedStuItem.getName());
            if (selectedStuItem.getSex().equals("男")) {
                rMan.setSelected(true);
            } else {
                rWoMan.setSelected(true);
            }
            dpAge.setValue(selectedStuItem.getAge());
            tScore.setText(String.valueOf(selectedStuItem.getScore()));
            //弹出编辑框
            Dialog<ButtonType> dialog = (Dialog) hashMap.get(AddOrEditDialog.ResultType.DIALOG);
            Optional<ButtonType> buttonType = dialog.showAndWait();
            if (buttonType.get() == ButtonType.OK) {

                //学生姓名判定*******************************************
                //用户输入完毕
                String name = tName.getText();
                //去掉空格
                name = name.trim();
                if (name.length() > 5 || name.length() == 0) {
                    throw new MyTextException("学生姓名错误");
                }
                //学生年龄判定*******************************************
                LocalDate value = dpAge.getValue();
                if (value == null) {
                    throw new MyTextException("请输入学生年龄");
                }
                //学生分数判定*******************************************
                //分数判断
                String score = tScore.getText();
                //转换
                Float fScore = Float.valueOf(score);
                //分数范围判定，因为这里将会直接修改学生对象，因此判定分数的范围放在控制器中直接判定
                //分数判断范围
                if (fScore < 0 || fScore > 100) {
                    throw new MyNumberException("分数范围为0-100");
                }
                //编辑
                selectedStuItem.setName(tName.getText());
                if (rMan.isSelected()) {
                    selectedStuItem.setSex("男");
                } else {
                    selectedStuItem.setSex("女");
                }
                selectedStuItem.setAge(dpAge.getValue());
                selectedStuItem.setScore(Float.valueOf(tScore.getText()));
                //表格要改变(这里就可以刷新了)
                table.refresh();
                //调用业务，但是业务什么都不做
                //因为table所要的集合就是DB.stus集合
                stuServices.edit(selectedStuItem);
            }
        } catch (MyTextException e) {
            MyAlert.alertOpen(e.getMessage(), "提示", ButtonType.CLOSE);
        } catch (NumberFormatException e) {
            MyAlert.alertOpen("输入的分数错误", "提示", ButtonType.CLOSE);
        } catch (Exception e) {
            e.printStackTrace();
            MyAlert.alertOpen("读取编辑窗口失败", "提示", ButtonType.CLOSE);
        }


    }

    @FXML
    void randomName(ActionEvent event) {
        //TODO 随机点名学生逻辑
        String num = tInputName.getText();
        try {
            int numCount = Integer.parseInt(num);
            //继续执行语句
            HashSet<Stu> randomStu = stuServices.getRandomStu(numCount);
            //打印随机学员
            StringBuilder stringBuilder = new StringBuilder();
            for (Stu stu : randomStu) {
                stringBuilder.append(stu.getName());
                //这里添加了\r\n回车，看看能不能换行
                stringBuilder.append("\r\n");
            }
            //弹出结果
            MyAlert.alertOpen(stringBuilder.toString(), "随机点名学员信息", ButtonType.CLOSE);

        } catch (NumberFormatException e) {
            e.printStackTrace();
            MyAlert.alertOpen("你输入的不是整数", "消息", ButtonType.CLOSE);
        } catch (MyNumberException e) {
            e.printStackTrace();
            MyAlert.alertOpen(e.getMessage(), "消息", ButtonType.CLOSE);
        } catch (Exception e) {
            e.printStackTrace();
            MyAlert.alertOpen("输入随机数个数的时候未知错误", "消息", ButtonType.CLOSE);
        }
    }

    @FXML
    void selectByAll(ActionEvent event) {
        //TODO 查询所有学生逻辑
        ArrayList<Stu> all = stuServices.getAll();
        ObservableList<Stu> stuObservableList = FXCollections.observableArrayList(all);
        table.setItems(stuObservableList);

    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        //TODO 初始化显示所有学生逻辑
        //获取学生数据集
        ArrayList<Stu> all = stuServices.getAll();
        //把学生数据集变换成ObservableList
        ObservableList<Stu> stuObservableList = FXCollections.observableArrayList(all);
        //清空表格列
        table.getColumns().clear();
        //表格的每一列绑定实体类的属性
        colId.setCellValueFactory(new PropertyValueFactory<Stu, Integer>("id"));
        colName.setCellValueFactory(new PropertyValueFactory<Stu, String>("name"));
        colSex.setCellValueFactory(new PropertyValueFactory<Stu, String>("sex"));
        colAge.setCellValueFactory(new PropertyValueFactory<Stu, LocalDate>("age"));
        colScore.setCellValueFactory(new PropertyValueFactory<Stu, Float>("score"));
        //表格添加每一列
        table.getColumns().addAll(colId, colName, colSex, colAge, colScore);
        //表格设置数据源
        table.setItems(stuObservableList);


    }
}
